<?php
App::uses('AppModel', 'Model');
/**
 * UserBuyProduct Model
 *
 * @property User $User
 * @property Product $Product
 */
class UserBuyProduct extends AppModel {

/**
 * Validation rules
 *
 * @var array
 */
	public $validate = array(
		'user_id' => array(
			'notempty' => array(
				'rule' => array('notempty'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'numeric' => array(
				'rule' => array('numeric'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'positive' => array(
				'rule' => array('validUserId'),
				'message' => 'Invalid user !!!'
				)
		),
		'product_id' => array(
			'notempty' => array(
				'rule' => array('notempty'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'numeric' => array(
				'rule' => array('numeric'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'positive' => array(
				'rule' => array('validProductId'),
				'message' => 'Invalid product !!!'
				)
		),
		'quantity' => array(
			'notempty' => array(
				'rule' => array('notempty'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'numeric' => array(
				'rule' => array('numeric'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'positive' => array(
				'rule' => array('validQuantity'),
				'message' => 'Invalid quantity !!!'
				)
		),
	);

	//The Associations below have been created with all possible keys, those that are not needed can be removed

/**
 * belongsTo associations
 *
 * @var array
 */
	public $belongsTo = array(
		'User' => array(
			'className' => 'User',
			'foreignKey' => 'user_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		),
		'Product' => array(
			'className' => 'Product',
			'foreignKey' => 'product_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		)
	);
	
	public function validUserId($data) {
		return ($data['user_id'] >= 0);
	}
	
	public function validProductId($data) {
		return ($data['product_id'] >= 0);
	}
	
	public function validQuantity($data) {
		return ($data['quantity'] > 0);
	}
	
	public function save_buy($data, $transactionFlag = false) {
		$dataSouce = $this->getDataSource();
		
		if ($transactionFlag) {
			$dataSouce->begin();
		}
		
		$this->create();
		$result = $this->save($data);
		
		if ($transactionFlag) {
			if ($result) {
				$dataSouce->commit();			
			} else {
				$dataSouce->rollback();
			}
		}
		
		return $result;
	}
	
	public function buy_case($userId, $productId, $quantity, $case) {
		App::import('Model', array('User', 'Product'));
		
		$modelProduct = new Product();
		$modelUser = new User();
		
		// Lay thong tin san pham
		$productInfo = $modelProduct->read(null, $productId);
		
		if (empty($productInfo)) {
			return 0;
		}
		
		// Start transaction
		$dataSource = $this->getDataSource();
		
		try {
			// Data save to UserBuyProduct
			$dataUserBuyProduct = array(
				'user_id' => $userId,
				'product_id' => $productId,
				'quantity' => $quantity
				);
				
			if ($case < 5) {
				$dataSource->begin();
			
				// Name modelUser (A), modelProduct(B), modelUserBuyProduct(C)
					
				switch ($case) {
					// TH1 : transaction include : A, B, C 
					case 1:
						$step1 = $modelUser->sub_balance($userId, $quantity * $productInfo['Product']['price'], false);
						$step2 = $modelProduct->sub_in_stock($productId, $quantity, false);
						$step3 = $this->save_buy($dataUserBuyProduct, false);
						
						$result = $step1 && $step2 && $step3; 
					break;
					
					//TH2 : transaction include : 1 transaction A, 1 transaction B, 1 transaction C
					case 2:
//						$dataSource->useNestedTransactions = true;
						$step1 = $modelUser->sub_balance($userId, $quantity * $productInfo['Product']['price'], true);
						$step2 = $modelProduct->sub_in_stock($productId, $quantity, true);
						$step3 = $this->save_buy($dataUserBuyProduct, true);
						
						$result = $step1 && $step2 && $step3;
					break;
					
					// TH3 : transaction include: 1 transaction A, 1 transaction B, C
					case 3:
//						$dataSource->useNestedTransactions = true;
						$step1 = $modelUser->sub_balance($userId, $quantity * $productInfo['Product']['price'], true);
						$step2 = $modelProduct->sub_in_stock($productId, $quantity, true);
						$step3 = $this->save_buy($dataUserBuyProduct, false);
						
						$result = $step1 && $step2 && $step3;
					break;
					
					// TH4 : transaction include: 1 transaction A, B, C
					case 4:
						$step1 = $modelUser->sub_balance($userId, $quantity * $productInfo['Product']['price'], true);
						$step2 = $modelProduct->sub_in_stock($productId, $quantity, false);
						$step3 = $this->save_buy($dataUserBuyProduct, false);
						
						$result = $step1 && $step2 && $step3;
					break;
					
					default:
						$step1 = $modelUser->sub_balance($userId, $quantity * $productInfo['Product']['price'], false);
						$step2 = $modelProduct->sub_in_stock($productId, $quantity, false);
						$step3 = $this->save_buy($dataUserBuyProduct, false);
						
						$result = $step1 && $step2 && $step3; 
					break;
				}
				
				if ($result) {
					$dataSource->commit();
				} else {
					$dataSource->rollback();
				}
			} else {
/*				$dataSource->useNestedTransactions = true;
				$dataSource->begin();*/
				
				$step1 = $modelUser->sub_balance($userId, $quantity * $productInfo['Product']['price'], true);
				$step2 = $modelProduct->sub_in_stock($productId, $quantity, true);
				$step3 = $this->save_buy($dataUserBuyProduct, true);
				
				$result = $step1 && $step2 && $step3;
				
				/*$result1 = $modelUser->sub_balance($userId, $quantity * $productInfo['Product']['price'], true);
				$result2 = $modelProduct->sub_in_stock($productId, $quantity, true);
				$result3 = $this->save_buy($dataUserBuyProduct, true);
				
				$result = $result1 && $result2 && $result3;*/
				
				/*if ($result) {
					$dataSource->commit();
				} else {
					$dataSource->rollback();
				}*/
//				$dataSource->commit();
			}
			
			return $result;
		} catch (Exception $e) {
			Object::log($e, 'UserBuyProduct_error');
			$dataSource->rollback();
		}
	}
}
